package com.finance.cooperate.feature.service.impl;

import com.finance.cooperate.common.utils.DateUtils;
import com.finance.cooperate.common.utils.StringUtil;
import com.finance.cooperate.dao.entity.primary.CrcConsultas;
import com.finance.cooperate.dao.local.cache.CrcCache;
import com.finance.cooperate.dao.local.scope.CooperateRequestScope;
import com.finance.cooperate.dao.repository.primary.CrcConsultasRepository;
import com.finance.cooperate.feature.service.CrcConsultasService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @ClassName CrcConsultasServiceImpl
 * @Description TODO
 * @Author shen
 * @Date 2023/8/9 15:34
 * @Modify ...
 */
@Service
@Slf4j
public class CrcConsultasServiceImpl implements CrcConsultasService {

    @Autowired
    private CrcConsultasRepository consultasRepository;

    @Autowired
    private CooperateRequestScope requestScope;


    @Override
    public Map<String, Object> getInfo(String uid) {

        Map<String, Object> result = new HashMap<>();

        String applyId = requestScope.getApplyId();

        List<CrcConsultas> consultas = consultasRepository.findByApplyId(applyId);

        if (consultas.size() > 0) {

            result.put("have_consultas", 1);

            // 1. 时间切片：总个数，分类个数，MX总金额，类型个数，最大金额，最小金额，平均金额

            for (CrcConsultas crc : consultas) {

                Date crcDate = DateUtils.toDate(crc.getFechaConsulta(), DateUtils.YYYY_MM_DD);

                // 用创建时间，不用进件时间
                // Date lastSubmitTime = requestScope.getLastSubmitTime();
                Date lastSubmitTime = crc.getCreateTime();

                Integer diffDays = DateUtils.getTimeDiffDays(crcDate, lastSubmitTime);

                if (diffDays >= 0) {

                    CrcCache.getTimeSplitsV1().forEach((k, v) -> {

                        if (diffDays <= v) {

                            // 需要的数据值
                            Integer grant = CrcCache.getGrantMap(crc.getNombreOtorgante());
                            String creditType = CrcCache.getCreditTypeMap(crc.getTipoCredito());
                            String currency = CrcCache.getCurrencyMap(crc.getClaveUnidadMonetaria());
                            String currAmount = crc.getImporteCredito();

                            if (!StringUtil.isEmptyOrNvl(grant)) {

                                if (!StringUtil.isEmptyOrNvl(creditType)) {

                                    if (!StringUtil.isEmptyOrNvl(currency)) {

                                        // ---------------------------

                                        // 计算信用总额度
                                        Long amount =  (Long) result.getOrDefault(
                                                String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_sum", k, grant, creditType, currency)
                                                , 0L);

                                        if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                            result.put(String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_sum", k, grant, creditType, currency)
                                                    , Double.valueOf(currAmount).longValue() + amount);
                                        }


                                        // 计算总个数
                                        Long count = (Long) result.getOrDefault(
                                                String.format("consultas_%s_grant_%d_credit_%s_currency_%s_count", k, grant, creditType, currency)
                                                , 0L
                                        );


                                        result.put(String.format("consultas_%s_grant_%d_credit_%s_currency_%s_count", k, grant, creditType, currency)
                                                , ++ count);

                                        // 计算最大额度
                                        Long amountMax =  (Long) result.getOrDefault(
                                                String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_max", k, grant, creditType, currency)
                                                , 0L);

                                        if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                            long currAmountL = Double.valueOf(currAmount).longValue();

                                            if (currAmountL > amountMax) {

                                                result.put(String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_max", k, grant, creditType, currency)
                                                        , currAmountL);

                                            }

                                        }

                                        // 计算最小额度
                                        Long amountMin =  (Long) result.getOrDefault(
                                                String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_min", k, grant, creditType, currency)
                                                , -1L);

                                        if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                            long currAmountL = Double.valueOf(currAmount).longValue();

                                            if (currAmountL > 0 && (currAmountL < amountMin || amountMin.equals(-1L))) {

                                                result.put(String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_min", k, grant, creditType, currency)
                                                        , currAmountL);

                                            }

                                        }

                                        // ---------------------------

                                    }

                                }


                                // ---------------------------

                                if (!StringUtil.isEmptyOrNvl(currency)) {
                                    // 计算信用总额度
                                    Long amount =  (Long) result.getOrDefault(
                                            String.format("consultas_%s_grant_%d_currency_%s_amount_sum", k, grant, currency)
                                            , 0L);

                                    if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                        result.put(String.format("consultas_%s_grant_%d_currency_%s_amount_sum", k, grant, currency)
                                                , Double.valueOf(currAmount).longValue() + amount);
                                    }


                                    // 计算总个数
                                    Long count = (Long) result.getOrDefault(
                                            String.format("consultas_%s_grant_%d_currency_%s_count", k, grant, currency)
                                            , 0L
                                    );


                                    result.put(String.format("consultas_%s_grant_%d_currency_%s_count", k, grant, currency)
                                            , ++ count);

                                    // 计算最大额度
                                    Long amountMax =  (Long) result.getOrDefault(
                                            String.format("consultas_%s_grant_%d_currency_%s_amount_max", k, grant, currency)
                                            , 0L);

                                    if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                        long currAmountL = Double.valueOf(currAmount).longValue();

                                        if (currAmountL > amountMax) {

                                            result.put(String.format("consultas_%s_grant_%d_currency_%s_amount_max", k, grant, currency)
                                                    , currAmountL);

                                        }

                                    }

                                    // 计算最小额度
                                    Long amountMin =  (Long) result.getOrDefault(
                                            String.format("consultas_%s_grant_%d_currency_%s_amount_min", k, grant, currency)
                                            , -1L);

                                    if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                        long currAmountL = Double.valueOf(currAmount).longValue();

                                        if (currAmountL > 0 && (currAmountL < amountMin || amountMin.equals(-1L))) {

                                            result.put(String.format("consultas_%s_grant_%d_currency_%s_amount_min", k, grant, currency)
                                                    , currAmountL);

                                        }

                                    }
                                }


                                // 计算授信人类别数
                                Set<Integer> grantSet = (Set<Integer>) result.getOrDefault(
                                        String.format("consultas_%s_grant_set", k)
                                        , new HashSet<Integer>()
                                );
                                grantSet.add(grant);

                                result.put(String.format("consultas_%s_grant_set", k), grantSet);


                                // 计算同类别人下各类型个数
                                if (!StringUtil.isEmptyOrNvl(creditType)) {

                                    Set<String> creditTypeSet = (Set<String>) result.getOrDefault(
                                            String.format("consultas_%s_grant_%d_credit_type_set", k, grant)
                                            , new HashSet<String>()
                                    );

                                    creditTypeSet.add(creditType);

                                    result.put(String.format("consultas_%s_grant_%d_credit_type_set", k, grant), creditTypeSet);


                                }


                                // ---------------------------

                            }

                            if (!StringUtil.isEmptyOrNvl(creditType)) {

                                // ---------------------------

                                if (!StringUtil.isEmptyOrNvl(currency)) {
                                    // 计算信用总额度
                                    Long amount =  (Long) result.getOrDefault(
                                            String.format("consultas_%s_credit_%s_currency_%s_amount_sum", k, creditType, currency)
                                            , 0L);

                                    if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                        result.put(String.format("consultas_%s_credit_%s_currency_%s_amount_sum", k, creditType, currency)
                                                , Double.valueOf(currAmount).longValue() + amount);
                                    }


                                    // 计算总个数
                                    Long count = (Long) result.getOrDefault(
                                            String.format("consultas_%s_credit_%s_currency_%s_count", k, creditType, currency)
                                            , 0L
                                    );


                                    result.put(String.format("consultas_%s_credit_%s_currency_%s_count", k, creditType, currency)
                                            , ++ count);

                                    // 计算最大额度
                                    Long amountMax =  (Long) result.getOrDefault(
                                            String.format("consultas_%s_credit_%s_currency_%s_amount_max", k, creditType, currency)
                                            , 0L);

                                    if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                        long currAmountL = Double.valueOf(currAmount).longValue();

                                        if (currAmountL > amountMax) {

                                            result.put(String.format("consultas_%s_credit_%s_currency_%s_amount_max", k, creditType, currency)
                                                    , currAmountL);

                                        }

                                    }

                                    // 计算最小额度
                                    Long amountMin =  (Long) result.getOrDefault(
                                            String.format("consultas_%s_credit_%s_currency_%s_amount_min", k, creditType, currency)
                                            , -1L);

                                    if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                        long currAmountL = Double.valueOf(currAmount).longValue();

                                        if (currAmountL > 0 && (currAmountL < amountMin || amountMin.equals(-1L))) {

                                            result.put(String.format("consultas_%s_credit_%s_currency_%s_amount_min", k, creditType, currency)
                                                    , currAmountL);

                                        }

                                    }
                                }


                                // 计算授信类型个数
                                Set<String> creditTypeSet = (Set<String>) result.getOrDefault(
                                        String.format("consultas_%s_credit_type_set", k)
                                        , new HashSet<String>()
                                );
                                creditTypeSet.add(creditType);

                                result.put(String.format("consultas_%s_credit_type_set", k), creditTypeSet);


                                // ---------------------------

                            }



                            if (!StringUtil.isEmptyOrNvl(currency)) {

                                // ---------------------------
                                // 计算信用总额度
                                Long amount =  (Long) result.getOrDefault(
                                        String.format("consultas_%s_currency_%s_amount_sum", k, currency)
                                        , 0L);

                                if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                    result.put(String.format("consultas_%s_currency_%s_amount_sum", k, currency)
                                            , Double.valueOf(currAmount).longValue() + amount);
                                }


                                // 计算总个数
                                Long count = (Long) result.getOrDefault(
                                        String.format("consultas_%s_currency_%s_count", k, currency)
                                        , 0L
                                );


                                result.put(String.format("consultas_%s_currency_%s_count", k, currency)
                                        , ++ count);



                                // 计算最大额度
                                Long amountMax =  (Long) result.getOrDefault(
                                        String.format("consultas_%s_currency_%s_amount_max", k, currency)
                                        , 0L);

                                if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                    long currAmountL = Double.valueOf(currAmount).longValue();

                                    if (currAmountL > amountMax) {

                                        result.put(String.format("consultas_%s_currency_%s_amount_max", k, currency)
                                                , currAmountL);

                                    }

                                }

                                // 计算最小额度
                                Long amountMin =  (Long) result.getOrDefault(
                                        String.format("consultas_%s_currency_%s_amount_min", k, currency)
                                        , -1L);

                                if (!StringUtil.isEmptyOrNvl(currAmount)) {

                                    long currAmountL = Double.valueOf(currAmount).longValue();

                                    if (currAmountL > 0 && (currAmountL < amountMin || amountMin.equals(-1L))) {

                                        result.put(String.format("consultas_%s_currency_%s_amount_min", k, currency)
                                                , currAmountL);

                                    }

                                }

                                // ---------------------------

                            }

                        }



                    });





                }




            }






            // 整体的变量衍生


            // #############################


            CrcCache.getTimeSplitsV1().forEach((tk, tv) -> {

                CrcCache.getGrantMapValues().forEach(gv -> {

                    CrcCache.getCreditTypeMapValues().forEach(cv -> {

                        CrcCache.getCurrencyMapValues().forEach(crv -> {

                            Long amountSum =  (Long) result.getOrDefault(
                                    String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_sum", tk, gv, cv, crv)
                                    , 0L);

                            Long count = (Long) result.getOrDefault(
                                    String.format("consultas_%s_grant_%d_credit_%s_currency_%s_count", tk, gv, cv, crv)
                                    , 0L
                            );

                            if (count > 0) {

                                result.put(
                                        String.format("consultas_%s_grant_%d_credit_%s_currency_%s_amount_avg", tk, gv, cv, crv)
                                        , (double) amountSum / count
                                );

                            }


                        });

                    });

                    CrcCache.getCurrencyMapValues().forEach(crv -> {

                        Long amountSum =  (Long) result.getOrDefault(
                                String.format("consultas_%s_grant_%d_currency_%s_amount_sum", tk, gv, crv)
                                , 0L);

                        Long count = (Long) result.getOrDefault(
                                String.format("consultas_%s_grant_%d_currency_%s_count", tk, gv, crv)
                                , 0L
                        );

                        if (count > 0) {
                            result.put(
                                    String.format("consultas_%s_grant_%d_currency_%s_amount_avg", tk, gv, crv)
                                    , (double) amountSum / count
                            );
                        }

                    });

                });


                CrcCache.getCreditTypeMapValues().forEach(cv -> {

                    CrcCache.getCurrencyMapValues().forEach(crv -> {

                        Long amountSum =  (Long) result.getOrDefault(
                                String.format("consultas_%s_credit_%s_currency_%s_amount_sum", tk, cv, crv)
                                , 0L
                        );

                        Long count = (Long) result.getOrDefault(
                                String.format("consultas_%s_credit_%s_currency_%s_count", tk, cv, crv)
                                , 0L
                        );


                        if (count > 0) {
                            result.put(
                                    String.format("consultas_%s_credit_%s_currency_%s_amount_avg", tk, cv, crv)
                                    , (double) amountSum / count
                            );
                        }

                    });



                });


                CrcCache.getCurrencyMapValues().forEach(crv -> {

                    Long amountSum =  (Long) result.getOrDefault(
                            String.format("consultas_%s_currency_%s_amount_sum", tk, crv)
                            , 0L);

                    Long count = (Long) result.getOrDefault(
                            String.format("consultas_%s_currency_%s_count", tk, crv)
                            , 0L
                    );

                    if (count > 0) {
                        result.put(
                                String.format("consultas_%s_currency_%s_amount_avg", tk, crv)
                                , (double) amountSum / count
                        );
                    }

                });


                Set<Integer> grantSet = (Set<Integer>) result.getOrDefault(
                        String.format("consultas_%s_grant_set", tk)
                        , new HashSet<Integer>()
                );

                result.put(String.format("consultas_%s_grant_size", tk), grantSet.size());


                Set<String> creditTypeSet = (Set<String>) result.getOrDefault(
                        String.format("consultas_%s_credit_type_set", tk)
                        , new HashSet<String>()
                );

                result.put(String.format("consultas_%s_credit_type_size", tk), creditTypeSet.size());


            });


        }


        return result;
    }


}
